package com.mijie.homi.api;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mijie.core.ApplicationProperties;
import com.mijie.core.Status;
import com.mijie.homi.common.constant.HomiConstants;
import com.mijie.homi.common.constant.HomiStatusCode;
import com.mijie.homi.common.domain.user.DeviceInfo;
import com.mijie.homi.common.domain.user.ThirdPartAccount;
import com.mijie.homi.common.domain.user.ThirdPartOfficialAccount;
import com.mijie.homi.common.domain.user.User;
import com.mijie.homi.common.domain.user.UserExtInfo;
import com.mijie.homi.service.common.StatService;
import com.mijie.homi.service.user.ThirdPartAccountService;
import com.mijie.homi.service.user.UserService;
import com.mijie.homi.util.ServerHelper;
import com.mijie.util.FileUploadUtil;
import com.mijie.util.Helper;
import com.mijie.util.IOUtil;
import com.mijie.util.ImageUtil;

@Controller
@RequestMapping("/user/thirdpart")
public class ThirdPartAccountApi {

	@Autowired
	private ThirdPartAccountService thirdPartAccountService;
	@Autowired
	private UserService userService;
	@Autowired
	private StatService statService;
	
	private Logger logger = Logger.getLogger(ThirdPartAccountApi.class);
	
	@RequestMapping(value="/info/get",method=RequestMethod.GET)
	public @ResponseBody void getInfo(String accountId,int type,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		ThirdPartAccount account = thirdPartAccountService.getThirdPartAccount(accountId,type);
		if(account==null){
			status.setCode(HomiStatusCode.THIRDPART_ACCOUNT_NOT_FOUND);
		}else{
			User user = userService.getUserById(account.getUserId());
			JSONObject result = new JSONObject();
			result.accumulate("userId", user.getId());
			result.accumulate("nickName", user.getNickName());
			result.accumulate("followed", account.getFollowed());
			result.accumulate("passwd", Helper.base64encode(user.getPasswd()));
			status.setResult(result);
		}
		status.write();
	}
	
	@RequestMapping(value="/share",method=RequestMethod.POST)
	public @ResponseBody void share(HttpServletRequest request,HttpServletResponse response) throws IOException{
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		Status status = new Status(request,response);
		ThirdPartAccount account = thirdPartAccountService.getThirdPartAccount(json.getString("accountId"),json.getInt("type"));
		if(account!=null){
			thirdPartAccountService.share(account);
		}else{
			status.setCode(HomiStatusCode.THIRDPART_ACCOUNT_NOT_FOUND);
		}
		status.write();
	}
	
	@RequestMapping(value="/official/follow",method=RequestMethod.GET)
	public @ResponseBody void follow(String accountId,int type,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		thirdPartAccountService.followThirdPartOfficialAccount(accountId, type);
		status.write();
	}
	
	@RequestMapping(value="/official",method=RequestMethod.GET)
	public @ResponseBody void getOfficialAccount(int type,HttpServletRequest request,HttpServletResponse response){
		Status status = new Status(request,response);
		ThirdPartOfficialAccount officialAccount = thirdPartAccountService.getOfficialAccount(type);
		if(officialAccount==null){
			status.setResult("{\"accountId\":\"\",\"title\":\"\",\"tweet\":\"\",\"link\":\"\",\"websiteName\":\"\",\"websiteLink\":\"\"}");
		}else{
			JSONObject result = JSONObject.fromObject(officialAccount);
			result.remove("type");
			status.setResult(result);
		}
		status.write();
	}
	
	@RequestMapping(value="/info/update",method=RequestMethod.POST)
	public @ResponseBody void updateInfo(HttpServletRequest request,HttpServletResponse response) throws IOException{
		Status status = new Status(request,response);
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		ThirdPartAccount account = thirdPartAccountService.getThirdPartAccount(json.getString("accountId"),json.getInt("type"));
		if(account==null){
			status.setCode(HomiStatusCode.THIRDPART_ACCOUNT_NOT_FOUND);
		}else{
			account.setAccessToken(json.getString("accessToken"));
			account.setAccountName(json.getString("accountName"));
			int rows = thirdPartAccountService.updateThirdPartAccount(account);
			if(rows==0)
				status.setCode(HomiStatusCode.API_EXCEPTION);
		}
		status.write();
	}
	
	
	@RequestMapping(value="/bind",method=RequestMethod.POST)
	public @ResponseBody void bind(HttpServletRequest request,HttpServletResponse response) throws Exception {
		String content = IOUtil.getContent4InputStream(request.getInputStream());
		JSONObject json = JSONObject.fromObject(content);
		String email = json.getString("email").trim();
		String passwd = json.getString("passwd");
		String nickName = json.getString("nickName").trim();
		
		Status status = new Status(request,response);
		
		if(!json.containsKey("accessToken")){
			status.setCode(HomiStatusCode.PARAM_ABSENT);
			status.write();
			logger.info("bind fail miss access token.");
			return;
		}
		
		if(!email.isEmpty()){
			if(!Helper.isEmail(email)){
				status.setCode(HomiStatusCode.EMAIL_FORMAT_ERROR);
				status.write();
				logger.info("bind fail EMAIL_FORMAT_ERROR.");
				return;
			}
		}
		
		
		if(Helper.isInt(nickName)){
			status.setCode(HomiStatusCode.NICKNAME_FORMAT_ERROR);
			status.write();
			logger.info("bind fail NICKNAME_FORMAT_ERROR.");
			return;
		}
		
		if(nickName.length()>HomiConstants.MAX_LENGTH_NICKNAME){
			nickName = nickName.substring(0,HomiConstants.MAX_LENGTH_NICKNAME);
		}
		
		User user = null;
		if(!email.isEmpty()){
			user = userService.getUserByEmail(email);
			if(user!=null  && !user.getPasswd().equals(passwd)){
				status.setCode(HomiStatusCode.EMAIL_OCCUPIED);
				status.write();
				logger.info("bind fail EMAIL_OCCUPIED.");
				return;
			}
		}
		
		ThirdPartOfficialAccount officialAccount = thirdPartAccountService.getOfficialAccount(json.getInt("type"));
		
		ThirdPartAccount account = new ThirdPartAccount();
		account.setType(json.getInt("type"));
		account.setAccessToken(json.getString("accessToken"));
		account.setAccountId(json.getString("accountId"));
		account.setAccountName(json.getString("accountName"));
		
		//新用户
		if(user==null){
			user = new User();
			user.setNickName(nickName);
			user.setPasswd(passwd);
			user.setGender(json.getInt("gender"));
			user.setSignature(json.getString("signature"));
			user.setProvince(json.getString("province"));
			user.setCity(json.getString("city"));
			user.setEmail(email);
			if(!email.isEmpty())
				user.setEmailVerified(1);
			String avatar = null;
			if(!json.getString("avatar").trim().isEmpty()){
				String avatarLargeHome = ApplicationProperties.get("avatar.large.home");
				String avatarSmalleHome = ApplicationProperties.get("avatar.small.home");
				String basePath = ApplicationProperties.get("resource.path");
				try{
					URL url  = new URL(json.getString("avatar"));
					String imageName = FileUploadUtil.upload(url.openStream(), ".jpg", basePath+avatarLargeHome);
					File src = new File(basePath+avatarLargeHome+imageName);
					if(src.exists()){
						File dest = new File(basePath+avatarSmalleHome+imageName);
						ImageUtil.zoomWithFixWidth(src, dest, 150, 0.8f);
					}
					if(imageName!=null)
						avatar = avatarSmalleHome+imageName;
				}catch(Exception e){
					
				}
			}
			
			UserExtInfo extInfo = new UserExtInfo();
			extInfo.setGender(user.getGender());
			extInfo.setLatitude(json.getDouble("latitude"));
			extInfo.setLongitude(json.getDouble("longitude"));
			extInfo.setLocationUpdateAt(new Date());
			extInfo.setTerminalId(json.getString("terminalId"));
			
			DeviceInfo deviceInfo = new DeviceInfo();
			deviceInfo.setCracked(json.getInt("cracked"));
			deviceInfo.setDeviceId(json.getString("deviceId"));
			deviceInfo.setDeviceName(json.getString("deviceName"));
			deviceInfo.setOperators(json.getString("operators"));
			deviceInfo.setOs(json.getString("os").toLowerCase());
			deviceInfo.setOsVer(json.getString("osVer"));
			deviceInfo.setPhoneModel(json.getString("phoneModel"));
			deviceInfo.setScreenSize(json.getString("screenSize"));
			deviceInfo.setMac(json.getString("mac"));
			deviceInfo.setAppVer(json.getString("appVer"));
			
			
			int id = userService.register(ServerHelper.getChannel(request),account.getType(),user,extInfo,deviceInfo);
			if(id>0){
				if(avatar!=null)
					userService.settingAvatar(id, avatar);
				JSONObject result = new JSONObject();
				result.accumulate("id", id);
				account.setUserId(id);
				id = thirdPartAccountService.addThirdPartAccount(account);
				result.accumulate("accountId", "");//默认不成功
				result.accumulate("tweet", officialAccount==null?"":officialAccount.getTweet());
				if(id>0) 
					result.put("accountId", account.getAccountId());
				status.setResult(result);
			}else{
				logger.info("bind fail DATABASE_EXCEPTION[newer]");
				status.setCode(HomiStatusCode.API_EXCEPTION);
			}
		}else{
			//已存在的用户,但是没有绑定
			account.setUserId(user.getId());
			int rows = thirdPartAccountService.addThirdPartAccount(account);
			JSONObject result = null;
			if(officialAccount==null){
				result = new JSONObject();
				result.put("accountId", "");//默认不成功
				result.accumulate("title", "");
				result.accumulate("tweet", "");
				result.accumulate("link", "");
				result.accumulate("websiteName", "");
				result.accumulate("websiteLink", "");
			}else{
				result = JSONObject.fromObject(officialAccount);
				result.remove("type");
			}
			result.put("id", user.getId());
			if(rows>0){
				result.put("accountId", account.getAccountId());
				status.setResult(result);
			}else{
				status.setCode(HomiStatusCode.API_EXCEPTION);
				logger.info("bind fail DATABASE_EXCEPTION[bind fail]");
			}
		}
		status.write();
	}
}
